namespace GYLite{
    export class ColorUtil{
		/**翻转rgb的顺序为bgr*/
        public static revertColor(color:number):number
		{
			let r:number,g:number,b:number,tintColor:number;            
			r = color >> 16;
			g = (color >> 8) & 0xff;
			b = color & 0xff;
			tintColor = (b << 16) + (g << 8) + r;
			return tintColor;
		}
		/**获取0-color之间的百分比颜色*/
		public static lerpColor(color:number,per:number):number
		{
			let r:number,g:number,b:number;
			r = color >> 16;
			g = (color >> 8) & 0xff;
			b = color & 0xff;
			r = r * per|0;
			g = g * per|0;
			b = b * per|0;
			return (r << 16)|(g<<8)|b;
		}
		public static getRGBColor(r:number,g:number,b:number):number
		{
			return (r << 16)|(g<<8)|b;
		}
		public static getARGBColor(r:number,g:number,b:number,a:number=1):number
		{
			return (a<<24)|(r << 16)|(g<<8)|b;
		}
		public static getColorARGB(color:number):number[]
		{
			let A:number,R:number,G:number,B:number;
			A = color >>> 24 & 0xff;
			R = color >>> 16 & 0xff;
			G = color >>> 8 & 0xff;
			B = color & 0xff;
			return [A,R,G,B];
		}
		/**16进制数值转成16进制颜色值
		 * @param c 如 #ffffff，返回0xffffff
		*/
		public static numberTo16Str(c:number):string
		{			
			return "#"+c.toString(16);
		}
		/**16进制颜色值转成16进制数值
		 * @param c 如 #ffffff，返回0xffffff
		*/
		public static str16ToNumber(c:string):number
		{
			return c?Number(c.replace("#", "0x")):0;
		}
		/**argb16进制颜色值转成16进制数值
		 * @param c 如 #ffffffff，返回[0xff,0xffffff]
		*/
		public static argb16ToNumber(c:string):number[]
		{
			c = c.replace("#", "");
			let alpha:number = Number("0x" + c.substring(0, 2));
			let color:number = Number("0x" + c.substring(2, c.length));
			return [alpha, color];
		}

		/**调整颜色color(argb)亮度，亮度系数 brightness（建议范围 -1.0~1.0）*/
		public static brightness(color:number, brightness:number):number
		{
			let A:number,R:number,G:number,B:number;
			let adjusted_R:number,adjusted_G:number,adjusted_B:number;
			[A, R, G, B] = ColorUtil.getColorARGB(color);						
			adjusted_R = MathUtil.clamp(R * (1 + brightness), 0, 255);
			adjusted_G = MathUtil.clamp(G * (1 + brightness), 0, 255);
			adjusted_B = MathUtil.clamp(B * (1 + brightness), 0, 255);
			return ColorUtil.getARGBColor(A, adjusted_R, adjusted_G, adjusted_B);
		}
		/**调整颜色color(argb)对比度，对比度系数 contrast（建议范围 0.0~2.0，1.0为原图）*/
		public static contrast(color:number, contrast:number):number
		{
			let A:number,R:number,G:number,B:number;
			let adjusted_R:number,adjusted_G:number,adjusted_B:number;
			let midpoint:number = 128;
			[A, R, G, B] = ColorUtil.getColorARGB(color);			
			adjusted_R = MathUtil.clamp((R - midpoint) * contrast + midpoint, 0, 255);
			adjusted_G = MathUtil.clamp((G - midpoint) * contrast + midpoint, 0, 255);
			adjusted_B = MathUtil.clamp((B - midpoint) * contrast + midpoint, 0, 255);
			return ColorUtil.getARGBColor(A, adjusted_R, adjusted_G, adjusted_B);
		}	
		/**调整颜色color(argb)饱和度，saturation（0.0为灰度，1.0为原图）*/
		public static saturation(color:number, saturation:number):number
		{
			let A:number,R:number,G:number,B:number;
			let adjusted_R:number,adjusted_G:number,adjusted_B:number;
			let gray:number;
			[A, R, G, B] = ColorUtil.getColorARGB(color);
			gray = 0.299 * R + 0.587 * G + 0.114 * B;//计算亮度（灰度值）
			adjusted_R = MathUtil.clamp(gray + (R - gray) * saturation, 0, 255);
			adjusted_G = MathUtil.clamp(gray + (G - gray) * saturation, 0, 255);
			adjusted_B = MathUtil.clamp(gray + (B - gray) * saturation, 0, 255);
			return ColorUtil.getARGBColor(A, adjusted_R, adjusted_G, adjusted_B);
		}	
		/**调整颜色color(argb)色相
		* 输入：原像素值 R, G, B，色相偏移角度 hue_shift（0-360度）
		* 步骤：将 RGB 转换为 HSL/HSV → 调整 H → 转回 RGB
		*/
		public static hue(color:number, hue_shift:number):number
		{
			let A:number,R:number,G:number,B:number;
			let adjusted_R:number,adjusted_G:number,adjusted_B:number;
			let gray:number;
			[A, R, G, B] = ColorUtil.getColorARGB(color);
			let [h, l, s] = ColorUtil.rgb_to_hls(R/255, G/255, B/255);
			h = (h + hue_shift/360) % 1.0; //色相偏移并取模			
			[adjusted_R, adjusted_G, adjusted_B] = ColorUtil.hls_to_rgb(h, l, s);
			adjusted_R = MathUtil.clamp(adjusted_R * 255, 0, 255);
			adjusted_G = MathUtil.clamp(adjusted_G * 255, 0, 255);
			adjusted_B = MathUtil.clamp(adjusted_B * 255, 0, 255);			
			return ColorUtil.getARGBColor(A, adjusted_R, adjusted_G, adjusted_B);
		}
		/**RGB转hls，RGB值传入前要归一化*/
		public static rgb_to_hls(R:number,G:number,B:number):number[]
		{			
			let h:number,l:number,s:number;			
			let max_val:number = Math.max(R, G, B);
			let min_val:number = Math.min(R, G, B);
    		l = (max_val + min_val) / 2.0;  //# 计算亮度
			if(max_val == min_val)
			{
				//灰度情况（色相和饱和度均为0）
				h = 0.0
				s = 0.0
			}        
			else
			{
				//计算饱和度
				if(l <= 0.5)
					s = (max_val - min_val) / (max_val + min_val)
				else
					s = (max_val - min_val) / (2.0 - max_val - min_val)

				//计算色相
				let delta:number = max_val - min_val
				if(R == max_val)
					h = (G - B) / delta
				else if(G == max_val)
					h = 2.0 + (B - R) / delta
				else
					h = 4.0 + (R - G) / delta

				h = (h * 60.0) % 360.0;//转换为角度（0-360度）
			}
    		return [h, l, s];
		}
		public static hls_to_rgb(h:number, l:number, s:number):number[]
		{
			let R:number,G:number,B:number;
			let q:number,p:number
			// 处理色相范围（0-360度）
			h = h % 360.0
			h /= 360.0  // 归一化到 [0,1)
		
			if(s == 0.0)
				// 饱和度为0时，RGB均为亮度值
				return [l, l, l];
			
			// 辅助函数：计算临时变量
			function hue_to_rgb(p:number, q:number, t:number):number
			{
				t = t % 1.0
				if(t < 1/6)
					return p + (q - p) * 6 * t
				if(t < 1/2)
					return q
				if(t < 2/3)
					return p + (q - p) * (2/3 - t) * 6
				return p
			}		
			// 计算中间变量
			if(l < 0.5)
				q = l * (1 + s);
			else
				q = l + s - (l * s);
			p = 2 * l - q;
		
			// 计算 RGB 分量
			R = hue_to_rgb(p, q, h + 1/3)
			G = hue_to_rgb(p, q, h)
			B = hue_to_rgb(p, q, h - 1/3)
		
			return [R, G, B]
		}
		/**颜色转矩阵
		 * @param color ARGB 原色
		 * @param offset ARGB 颜色偏移量
		*/
		public static colorToMatrix(color:number,offset:number=0):number[]
		{
			let [a,r,g,b] = ColorUtil.getColorARGB(color);
			let [a2,r2,g2,b2] = ColorUtil.getColorARGB(offset);
			let colorMatrix = [
				1, 0, 0, 0, 0,
				0, 1, 0, 0, 0,
				0, 0, 1, 0, 0,
				0, 0, 0, 1, 0
			];
			colorMatrix[0] = r / 255;
			colorMatrix[6] = g / 255;
			colorMatrix[12] = b / 255;
			colorMatrix[18] = a / 255;
			colorMatrix[4] = r2 / 255;
			colorMatrix[9] = g2 / 255;
			colorMatrix[14] = b2 / 255;
			colorMatrix[19] = a2 / 255;
			return colorMatrix;
		}
    }
}